Introduction to igraph

James Holland Jones

12/20/2017

Getting Started

library(igraph)

Graphs

Some Definitions

Graph

Collection of vertices (or nodes) and undirected edges (or ties), denoted \(\mathcal{G}(V,E)\), where \(V\) is a the vertex set and \(E\) is the edge set.

Digraph (Directed Graph)

Collection of vertices (or nodes) and directed edges.

Bipartite Graph

Graph where all the nodes of a graph can be partitioned into two sets \(\mathcal{V}_1\) and \(\mathcal{V}_2\) such that for all edges in the graph connects and unordered pair where one vertex comes from \(\mathcal{V}_1\) and the other from \(\mathcal{V}_2\). Often called an “affiliation graph” as bipartite graphs are used to represent people’s affiliations to organizations or events.

Various Ways to Specify Graphs

require(igraph)
g <- make_graph( c(1,2, 1,3, 2,3, 2,4, 3,5, 4,5), n=5, dir=FALSE )
plot(g, vertex.color="lightblue")

g <- graph_from_literal(Fred-Daphne:Velma-Shaggy, Fred-Shaggy-Scooby)
plot(g, vertex.shape="none", vertex.label.color="black")

Special Graphs: Empty, Full, Ring

# empty graph
g0 <- make_empty_graph(20)
plot(g0, vertex.color="lightblue", vertex.size=10, vertex.label=NA)

# full graph
g1 <- make_full_graph(20)
plot(g1, vertex.color="lightblue", vertex.size=10, vertex.label=NA)

# ring
g2 <- make_ring(20)
plot(g2, vertex.color="lightblue", vertex.size=10, vertex.label=NA)

Special Graphs: Lattice, Tree, Star

# lattice
g3 <- make_lattice(dimvector=c(10,10))
plot(g3, vertex.color="lightblue", vertex.size=10, vertex.label=NA)

# tree
g4 <- make_tree(20, children = 3, mode = "undirected")
plot(g4, vertex.color="lightblue", vertex.size=10, vertex.label=NA)

# star
g5 <- make_star(20, mode="undirected")
plot(g5, vertex.color="lightblue", vertex.size=10, vertex.label=NA)

Special Graphs: Erdos-Renyi & Power-Law

# Erdos-Renyi Random Graph
g6 <- sample_gnm(n=100,m=50)
plot(g6, vertex.color="lightblue", vertex.size=5, vertex.label=NA)

# Power Law
g7 <- sample_pa(n=100, power=1.5, m=1,  directed=FALSE)
plot(g7, vertex.color="lightblue", vertex.size=5, vertex.label=NA)

Putting Graphs Together

plot(g4 %du% g7, vertex.color="lightblue", vertex.size=5, vertex.label=NA)

Rewiring

gg <- g4 %du% g7
gg <- rewire(gg, each_edge(prob = 0.3))
plot(gg, vertex.color="lightblue", vertex.size=5, vertex.label=NA)

## retain only the connected component
gg <- induced.subgraph(gg, subcomponent(gg,1))
plot(gg, vertex.color="lightblue", vertex.size=5, vertex.label=NA)

Vertex and Edge Attributes

## look at the structure
g4
## IGRAPH 3558487 U--- 20 19 -- Tree
## + attr: name (g/c), children (g/n), mode (g/c)
## + edges from 3558487:
##  [1] 1-- 2 1-- 3 1-- 4 2-- 5 2-- 6 2-- 7 3-- 8 3-- 9 3--10 4--11 4--12
## [12] 4--13 5--14 5--15 5--16 6--17 6--18 6--19 7--20
V(g4)$name <- LETTERS[1:20]
## see how it's changed
g4
## IGRAPH 3558487 UN-- 20 19 -- Tree
## + attr: name (g/c), children (g/n), mode (g/c), name (v/c)
## + edges from 3558487 (vertex names):
##  [1] A--B A--C A--D B--E B--F B--G C--H C--I C--J D--K D--L D--M E--N E--O
## [15] E--P F--Q F--R F--S G--T
## see what I did there?
## do some other stuff
V(g4)$vertex.color <- "Pink"
E(g4)$edge.color <- "SkyBlue2"
plot(g4, vertex.size=10, vertex.label=NA, vertex.color=V(g4)$vertex.color, 
     edge.color=E(g4)$edge.color, edge.width=3)

Adjacency Matrices

kids <- as.matrix(
  read.table("/Users/jhj1/Teaching/social_networks/data/strayer_strayer1976-fig2.txt",
                             header=FALSE)
  )
kid.names <- c("Ro","Ss","Br","If","Td","Sd","Pe","Ir","Cs","Ka",
                "Ch","Ty","Gl","Sa", "Me","Ju","Sh")
colnames(kids) <- kid.names
rownames(kids) <- kid.names
g <- graph_from_adjacency_matrix(kids, mode="directed", weighted=TRUE)
lay <- layout_with_fr(g)
plot(g,edge.width=log2(E(g)$weight)+1, layout=lay, vertex.color="lightblue")

Community Structure

A <- as.matrix(
  read.table(file="/Users/jhj1/Teaching/social_networks/code/kapferer-tailorshop1.txt", 
             header=TRUE, row.names=1)
  )
G <- graph.adjacency(A, mode="undirected", diag=FALSE)
fg <- fastgreedy.community(G)
cols <- c("blue","red","black","magenta")
plot(G, vertex.shape="none",
     vertex.label.cex=0.75, edge.color=grey(0.85), 
     edge.width=1, vertex.label.color=cols[fg$membership])

# another approach to visualizing
plot(fg,G,vertex.label=NA)

Laying Out Graphs By Hand

tkplot() window of triangle graph

tkplot() window of triangle graph

g <- graph( c(1,2, 2,3, 1,3), n=3, dir=FALSE)
plot(g)

#tkplot(g)
#tkplot.getcoords(1)
### do some stuff with tkplot() and get coords which we call tri.coords
## tkplot(g)
## tkplot.getcoords(1) ## the plot id may be different depending on how many times you've called tkplot()
##     [,1] [,2]
##[1,]  228  416
##[2,]  436    0
##[3,]   20    0
tri.coords <- matrix( c(228,416, 436,0, 20,0), nr=3, nc=2, byrow=TRUE)
par(mfrow=c(1,2))
plot(g, vertex.color="lightblue")
plot(g, layout=tri.coords, vertex.color="lightblue")

Plotting Affiliation Graphs

davismat <- as.matrix(
  read.table(file="/Users/jhj1/Teaching/social_networks/data/davismat.txt", 
            row.names=1, header=TRUE)
  )
southern <- graph_from_incidence_matrix(davismat) 
V(southern)$shape <- c(rep("circle",18), rep("square",14))
V(southern)$color <- c(rep("blue",18), rep("red", 14))
plot(southern, layout=layout.bipartite)

## not so beautiful
## did some tinkering using tkplot()...
x <- c(rep(23,18), rep(433,14))
y <- c(44.32432,   0.00000, 132.97297,  77.56757,  22.16216, 110.81081, 155.13514,
       199.45946, 177.29730, 243.78378, 332.43243, 410.00000, 387.83784, 354.59459,
       310.27027, 221.62162, 265.94595, 288.10811,   0.00000,  22.16216,  44.32432,
       66.48649,  88.64865, 132.97297, 166.21622, 199.45946, 277.02703, 365.67568,
       310.27027, 343.51351, 387.83784, 410.00000)
southern.layout <- cbind(x,y)
plot(southern, layout=southern.layout)

#Sociomatrix
(f2f <- davismat %*% t(davismat))
##           EVELYN LAURA THERESA BRENDA CHARLOTTE FRANCES ELEANOR PEARL RUTH
## EVELYN         8     6       7      6         3       4       3     3    3
## LAURA          6     7       6      6         3       4       4     2    3
## THERESA        7     6       8      6         4       4       4     3    4
## BRENDA         6     6       6      7         4       4       4     2    3
## CHARLOTTE      3     3       4      4         4       2       2     0    2
## FRANCES        4     4       4      4         2       4       3     2    2
## ELEANOR        3     4       4      4         2       3       4     2    3
## PEARL          3     2       3      2         0       2       2     3    2
## RUTH           3     3       4      3         2       2       3     2    4
## VERNE          2     2       3      2         1       1       2     2    3
## MYRNA          2     1       2      1         0       1       1     2    2
## KATHERINE      2     1       2      1         0       1       1     2    2
## SYLVIA         2     2       3      2         1       1       2     2    3
## NORA           2     2       3      2         1       1       2     2    2
## HELEN          1     2       2      2         1       1       2     1    2
## DOROTHY        2     1       2      1         0       1       1     2    2
## OLIVIA         1     0       1      0         0       0       0     1    1
## FLORA          1     0       1      0         0       0       0     1    1
##           VERNE MYRNA KATHERINE SYLVIA NORA HELEN DOROTHY OLIVIA FLORA
## EVELYN        2     2         2      2    2     1       2      1     1
## LAURA         2     1         1      2    2     2       1      0     0
## THERESA       3     2         2      3    3     2       2      1     1
## BRENDA        2     1         1      2    2     2       1      0     0
## CHARLOTTE     1     0         0      1    1     1       0      0     0
## FRANCES       1     1         1      1    1     1       1      0     0
## ELEANOR       2     1         1      2    2     2       1      0     0
## PEARL         2     2         2      2    2     1       2      1     1
## RUTH          3     2         2      3    2     2       2      1     1
## VERNE         4     3         3      4    3     3       2      1     1
## MYRNA         3     4         4      4    3     3       2      1     1
## KATHERINE     3     4         6      6    5     3       2      1     1
## SYLVIA        4     4         6      7    6     4       2      1     1
## NORA          3     3         5      6    8     4       1      2     2
## HELEN         3     3         3      4    4     5       1      1     1
## DOROTHY       2     2         2      2    1     1       2      1     1
## OLIVIA        1     1         1      1    2     1       1      2     2
## FLORA         1     1         1      1    2     1       1      2     2
gf2f <- graph_from_adjacency_matrix(f2f, mode="undirected", diag=FALSE, add.rownames=TRUE)
gf2f <- simplify(gf2f)
plot(gf2f, vertex.color="lightblue")

## who is the most central?
cb <- betweenness(gf2f)
#plot(gf2f,vertex.size=cb*10, vertex.color="lightblue")
plot(gf2f,vertex.label.cex=1+cb/2, vertex.shape="none")

### this gives you the number of women at each event (diagonal) or mutually at 2 events
(e2e <- t(davismat) %*% davismat)
##     E1 E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12 E13 E14
## E1   3  2  3  2  3  3  2  3  1   0   0   0   0   0
## E2   2  3  3  2  3  3  2  3  2   0   0   0   0   0
## E3   3  3  6  4  6  5  4  5  2   0   0   0   0   0
## E4   2  2  4  4  4  3  3  3  2   0   0   0   0   0
## E5   3  3  6  4  8  6  6  7  3   0   0   0   0   0
## E6   3  3  5  3  6  8  5  7  4   1   1   1   1   1
## E7   2  2  4  3  6  5 10  8  5   3   2   4   2   2
## E8   3  3  5  3  7  7  8 14  9   4   1   5   2   2
## E9   1  2  2  2  3  4  5  9 12   4   3   5   3   3
## E10  0  0  0  0  0  1  3  4  4   5   2   5   3   3
## E11  0  0  0  0  0  1  2  1  3   2   4   2   1   1
## E12  0  0  0  0  0  1  4  5  5   5   2   6   3   3
## E13  0  0  0  0  0  1  2  2  3   3   1   3   3   3
## E14  0  0  0  0  0  1  2  2  3   3   1   3   3   3
ge2e <- graph_from_adjacency_matrix(e2e, mode="undirected", diag=FALSE, add.rownames=TRUE)
ge2e <- simplify(ge2e)
plot(ge2e, vertex.color="lightblue")